package main

import "fmt"

func foo() {
	println("call foo")
	bar()
	println("exit foo")
}

func bar() {
	defer func() {
		println("执行bar函数")
		if e := recover(); e != nil {
			fmt.Println("recover the panic:", e)
		}
	}()

	println("call bar")
	panic("panic occurs in bar")
	zoo()
	println("exit bar")
}

func zoo() {
	println("call zoo")
	println("exit zoo")
}

func foo1() {
	for i := 0; i <= 3; i++ {
		defer fmt.Println(i) // 函数返回前, deferred函数是按照后入先出(LIFO)顺序执行的
	}
}

func foo2() {
	for i := 0; i <= 3; i++ {
		defer func(n int) {
			fmt.Println(n) // defer关键字是在注册函数时对函数的参数进行求值的
		}(i)
	}
}

func foo3() {
	for i := 0; i <= 3; i++ {
		defer func() {
			fmt.Println(i)
		}()
	}
}

func main() {
	fmt.Println("foo1 result:")
	foo1()
	fmt.Println("\nfoo2 result:")
	foo2()
	fmt.Println("\nfoo3 result:")
	foo3()

	println("call main")
	foo()
	println("exit main")
}
